package lru;

import java.util.HashMap;
import java.util.Map;
//TODO:2023/9/4     9月4日
public class LRUTest0829 {
    //TODO:2023/8/29  node  需要泛型
    class   Node<K,V>{
        K  key;
        V  value;
        Node<K,V>  pre;
        Node<K,V>  next;

        public  Node(){
            this.next=this.pre=null;
        }

        public  Node(K key,V value){
            this.key=key;
            this.value=value;
            this.next=this.pre=null;
        }
    }
    //TODO:2023/8/29  双向链表也需要泛型
    class  DoubleLinkedList<K,V>{
        Node<K,V>  head;
        Node<K,V> tail;
        public  DoubleLinkedList(){
            head=new Node<>();
            tail=new Node<>();
            head.next=tail;
            tail.pre=head;
        }

        public   void  addHead(Node<K,V> node){
            node.next=head.next;
            head.next.pre=node;
            head.next=node;
            node.pre=head;

        }
        //TODO:2023/9/4  removeNode 是有参数的

        public   void  removeNode(Node<K,V> node){
            node.next.pre=node.pre;
            node.pre.next=node.next;
            node.pre=null;
            node.next=null;
        }

        public  Node<K,V>  getLast(){
            //TODO:2023/9/4 这里的tail是一个空的node
            return  tail.pre;
        }
    }

    int capacity;
    //TODO:2023/9/4  下面的形式是错误的  这里的时候就需要将K V 传入实际的参数类型
//     Map<Integer,Node<K,V>>  map= new HashMap<>();
    Map<Integer,Node<Integer,Integer>> map;
    DoubleLinkedList<Integer,Integer>  doubleLinkedList;


   public   LRUTest0829(int capacity){
       this.capacity=capacity;
       this.map=new HashMap<>();
       this.doubleLinkedList=new DoubleLinkedList<>();
   }


//TODO:2023/9/4   最外层的get put 是  越简单越好就是针对 具体的数值  key  value
   public   int get(int key ){
       if (!map.containsKey(key)){
           return  -1;
       }
       Node<Integer, Integer> node = map.get(key);
       doubleLinkedList.removeNode(node);
       doubleLinkedList.addHead(node);
       return node.value;

   }

   public   void  put(int key,int value){
       if (map.containsKey(key)){
           Node<Integer, Integer> node = map.get(key);
           node.value=value;
           map.put(key,node);
           doubleLinkedList.removeNode(node);
           doubleLinkedList.addHead(node);
       }else {

           if (map.size()==capacity){
               Node<Integer, Integer> n = doubleLinkedList.getLast();
               doubleLinkedList.removeNode(n);
               map.remove(n.key);
           }
           Node<Integer, Integer> newNode = new Node<>(key, value);
           map.put(key,newNode);
           doubleLinkedList.addHead(newNode);

       }

   }

    public static void main(String[] args) {


        LRUTest0829 lruCacheDemo = new LRUTest0829(3);
        lruCacheDemo.put(1, 1);
        lruCacheDemo.put(2, 2);
        lruCacheDemo.put(3, 3);

//        for (:
//             lruCacheDemo.doubleLinkedList) {
//
//        }

        System.out.println(lruCacheDemo.map.keySet());

        lruCacheDemo.put(4, 1);
        System.out.println(lruCacheDemo.map.keySet());

        lruCacheDemo.put(3, 1);
        System.out.println(lruCacheDemo.map.keySet());
        lruCacheDemo.put(3, 1);
        System.out.println(lruCacheDemo.map.keySet());
        lruCacheDemo.put(3, 1);
        System.out.println(lruCacheDemo.map.keySet());
        lruCacheDemo.put(5, 1);
        System.out.println(lruCacheDemo.map.keySet());

    }


}






